
#include "giscoreao_dispatcher.h"
#include "erp/gis/comm/erp_gis_func_define.h"

#include "c2cent/library/log/CWTimeElf3.h"


using namespace c2cent::library::wwlog;
using namespace erp::gis::ao;
using namespace erp::gis::comm;



CDispatcher::CDispatcher(){}

CDispatcher::~CDispatcher()
{
	Destroy();
}


void CDispatcher::Destroy()
{
	std::map<uint32_t,erp::gis::ao::CAsynProtocol *>::iterator it = m_mapProtocol.begin();
	std::map<uint32_t,erp::gis::ao::CAsynProtocol *>::iterator itEnd = m_mapProtocol.end();
	for(; it != itEnd; it++)
	{
		delete it->second;
	}
	m_mapProtocol.clear();
}
uint32_t CDispatcher::Dispatch(
	const CCntlInfo& rCntlInfo,
	const std::string& strMachineKey,
	const std::string& strSource,
	uint32_t dwSceneId,
	const uint32_t dwChannel,
	const CAsynSendParamBo& oAsynSendParam,
	const std::string& strInReserve,
	CAsynRecvResultBo& oAsynRecvResult,
	erp::gis::ao::CLiber& oLiber) const
{
	uint32_t iRetCode = 0;
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG, __FUNCTION__, (int*)&iRetCode);

	oLiber.Reset();
	std::map<uint32_t,erp::gis::ao::CAsynProtocol *>::const_iterator it = m_mapProtocol.begin();
	std::map<uint32_t,erp::gis::ao::CAsynProtocol *>::const_iterator itEnd = m_mapProtocol.end();
	for(; it != itEnd; it++)
	{
		 it->second->Send(rCntlInfo, strMachineKey, strSource, dwSceneId, oAsynSendParam, strInReserve, oLiber);
	}

	if(oLiber.Empty())
	{
		C2C_WW_LOG("DispatchNum=0 Uin:%u", rCntlInfo.getOperatorUin());
		return iRetCode;
	}
	
	CCntlInfo* pCntlInfo = const_cast<CCntlInfo*>(&rCntlInfo);
	IServiceControl* pSvcCntl = reinterpret_cast<IServiceControl*>(pCntlInfo->getCntl());

	do{
		if((iRetCode = pSvcCntl->schedule()) != 0)
		{
			C2C_WW_LOG_FERR(iRetCode, "schedule() Timeouts ");
			iRetCode = Clear(rCntlInfo, strMachineKey, strSource, ERR_SYS_SCHEDULE_FAILED, oAsynSendParam, oLiber);
			return iRetCode;
		}
		CCmdObj& rCmd = pSvcCntl->getRespObj();
		it = m_mapProtocol.find(rCmd.getCmdId());
		if(it == itEnd)
		{
			C2C_WW_LOG_FERR(ERR_SYS_UNKNOWN_RESPONSE, "Unknown Response CmdId:%u ",
					rCmd.getCmdId());
			continue;
		}
		std::string strErrMsg;
		std::string strOutReserve;
		iRetCode=it->second->Receive(oAsynSendParam,dwChannel,rCmd,oAsynRecvResult,strErrMsg,strOutReserve,oLiber,oWTimeElf);
		Clear(rCntlInfo, strMachineKey, strSource, iRetCode, oAsynSendParam, oLiber);
	}
	while(!oLiber.Empty());
	
	return iRetCode;
}

uint32_t CDispatcher::Clear(
	const CCntlInfo& rCntlInfo,
	const std::string& strMachineKey,
	const std::string& strSource,
	const uint32_t iRetCode,
	const CAsynSendParamBo& oAsynSendParam,
	erp::gis::ao::CLiber& oLiber) const
{
	if(iRetCode != 0)
	{
		if(iRetCode == ERR_SYS_SCHEDULE_FAILED)
		{
			std::map<uint32_t,uint32_t>::const_iterator it=oLiber.GetLiber().begin();
			std::map<uint32_t,uint32_t>::const_iterator itEnd=oLiber.GetLiber().end();
			for(;it!=itEnd;it++)
			{
				if(it->second!=0)
				{
					std::map<uint32_t,erp::gis::ao::CAsynProtocol *>::const_iterator itMap = m_mapProtocol.find(it->first);
					if(itMap!=m_mapProtocol.end())
					{
						itMap->second->Check(iRetCode);
						C2C_WW_LOG_FERR(iRetCode, "%s Timeouts ", itMap->second->GetProtocolName().c_str());
					}
				}
			}
			oLiber.Clear();
		}
	}
	
	return iRetCode;
}


